/*******************************************************************************

  Pilot Intelligence Library
    https://gitee.com/pi-lab

*******************************************************************************/

#pragma once

#include <string>

////////////////////////////////////////////////////////////////////////////////
/// ASSERT macro
////////////////////////////////////////////////////////////////////////////////
#ifdef PI_DEBUG

    #define ASSERT(f) \
        do { \
            if (!f ) { \
                fprintf(stderr, "ERROR (FILE: %s, LINE: %d, FUNC: %s)\n", \
                    __FILE__, __LINE__, __FUNCTION__); \
                exit(1); \
            } \
        } while (0); \


    #define ASSERT2(f, s) \
        do { \
            if (!f ) { \
                fprintf(stderr, "ERROR: %s (FILE: %s, LINE: %d, FUNC: %s)\n", \
                    s, __FILE__, __LINE__, __FUNCTION__); \
                exit(1); \
            } \
        } while (0); \

#else
    #define ASSERT(f)
    #define ASSERT2(f, s)
#endif

////////////////////////////////////////////////////////////////////////////////
/// debug level
////////////////////////////////////////////////////////////////////////////////

#define PI_DEBUG_LEVEL_NOTEST      0
#define PI_DEBUG_LEVEL_TRACE       5
#define PI_DEBUG_LEVEL_DEBUG       10
#define PI_DEBUG_LEVEL_INFO        20      // default
#define PI_DEBUG_LEVEL_WARN        30
#define PI_DEBUG_LEVEL_ERROR       40
#define PI_DEBUG_LEVEL_FATAL       50

// debug level functions
void dbg_set_level(int i);
int  dbg_get_level(void);
void dbg_push_level(int i);
int  dbg_pop_level(void);


////////////////////////////////////////////////////////////////////////////////
/// usefull debug print functions
////////////////////////////////////////////////////////////////////////////////

// debug print functions
void dbg_printf(int level,
                const char *fname, int line, const char *func,
                const char *szFmtString, ...);


// critical message
#define dbg_pf(...) dbg_printf(PI_DEBUG_LEVEL_FATAL, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)

// error message
#define dbg_pe(...) dbg_printf(PI_DEBUG_LEVEL_ERROR, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)

// warning message
#define dbg_pw(...) dbg_printf(PI_DEBUG_LEVEL_WARN, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)

// information message (default)
#define dbg_pi(...) dbg_printf(PI_DEBUG_LEVEL_INFO, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)

// debug message
#define dbg_pd(...) dbg_printf(PI_DEBUG_LEVEL_DEBUG, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)

// trace message
#define dbg_pt(...) dbg_printf(PI_DEBUG_LEVEL_TRACE, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)

// notest message
#define dbg_pnt(...) dbg_printf(PI_DEBUG_LEVEL_NOTEST, __FILE__, __LINE__, __FUNCTION__, __VA_ARGS__)


////////////////////////////////////////////////////////////////////////////////
/// debug stack trace functions
////////////////////////////////////////////////////////////////////////////////
void dbg_stacktrace_setup(void);


////////////////////////////////////////////////////////////////////////////////
/// stdout, stderr to log file
////////////////////////////////////////////////////////////////////////////////
void log_toFile(const std::string& logFN);
